package elka.gis.postman.helper.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.log4j.Logger;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonIOException;

import elka.gis.postman.bean.Edge;
import elka.gis.postman.bean.Graph;
import elka.gis.postman.bean.Path;
import elka.gis.postman.bean.Vertex;
import elka.gis.postman.common.Constants;
import elka.gis.postman.helper.GraphReader;

/**
 * Klasa czyta grafy z okreslonej sciezki
 * @author Wojtek
 *
 */
public class GraphReaderImpl implements GraphReader {
	private final static Logger LOGGER = Logger.getLogger(GraphReaderImpl.class);
	private final static Gson GSON = new GsonBuilder().setPrettyPrinting().create();
	
	public Graph readGraphFromPath(String path) {
		try {
			BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
			Graph graph = GSON.fromJson(bufferedReader, Graph.class);
			addPathsToVertexes(graph);
			return graph;
		} catch (FileNotFoundException e) {
			LOGGER.error("Blad czytania pliku", e);
			throw new JsonIOException(Constants.IO_EXCEPTION_MSG, e);
		}
	}

	private void addPathsToVertexes(Graph graph) {
		Map<Integer, Vertex> vertexMap = createVertexMap(graph.getVertices());
		
		List<Edge> edges = graph.getEdges();
		
		for(int i=0; i<edges.size(); ++i) {
			Edge edge = edges.get(i);
			int idStartPoint = edge.getStartPoint().getId();
			int idEndPoint = edge.getEndPoint().getId();
			
			Vertex vertexStartPoint = vertexMap.get(idStartPoint);
			Vertex vertexEndPoint = vertexMap.get(idEndPoint);
			
			vertexStartPoint.getEdges().add(edge);
			vertexEndPoint.getEdges().add(edge);
		}
		
		for(int j=0;j<edges.size();++j) {
			Edge edge = edges.get(j);
			
			int idStartPoint = edge.getStartPoint().getId();
			int idEndPoint = edge.getEndPoint().getId();
			
			Vertex vertexStartPoint = vertexMap.get(idStartPoint);
			Vertex vertexEndPoint = vertexMap.get(idEndPoint);
			
			edge.setStartPoint(vertexStartPoint);
			edge.setEndPoint(vertexEndPoint);
		}
	}

	private Map<Integer, Vertex> createVertexMap(List<Vertex> vertices) {
		Map<Integer, Vertex> vertexMap = new TreeMap<Integer, Vertex>();
		
		for(Vertex vertex:vertices) {
			vertexMap.put(vertex.getId(), vertex);
		}
		
		return vertexMap;
	}

	public void savePath(Path path) {
		String pathJson = GSON.toJson(path);
        File newTextFile = new File("path.json");
        FileWriter fileWriter;
		try {
			fileWriter = new FileWriter(newTextFile);
	        fileWriter.write(pathJson);
	        fileWriter.close();
		} catch (IOException e) {
			LOGGER.error("Blad zapisu sciezki do pliku",e);
		}
	}

}
